#ifdef USE_BROKEN_UPDATER

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>

#define UPDATE_SERVER          L"hifi.iki.fi"
#define UPDATE_VERSION_FILE    L"/cncnetv2/version.txt"
#define UPDATE_FILE            L"/cncnetv2/cncnet.exe"

HINTERNET RequestSubmit(HINTERNET hSession, LPCWSTR host, LPCWSTR file);
DWORD RequestHeaderDWORD(HINTERNET hRequest, DWORD dwFlag);
char *RequestHeaderString(HINTERNET hRequest, DWORD dwFlag);
DWORD RequestDownloadToMemory(HINTERNET hRequest, char *cBuf, DWORD dwBufSize);
DWORD RequestDownloadToFile(HINTERNET hRequest, HANDLE hFile);

/* TRUE on successful update */
BOOL Updater()
{
    HINTERNET hSession;
    HINTERNET hRequest;

    DWORD dwStatus;
    DWORD dwLength;
    DWORD dwDownloaded;
    char *type;

    char lpPathName[MAX_PATH] = { 0 };
    char lpTempFileName[MAX_PATH] = { 0 };
    char lpModuleFileName[MAX_PATH] = { 0 };
    char lpMoveModuleFileName[MAX_PATH] = { 0 };
    GetModuleFileName(NULL, lpModuleFileName, MAX_PATH);
    GetModuleFileName(NULL, lpMoveModuleFileName, MAX_PATH);
    lpMoveModuleFileName[strlen(lpMoveModuleFileName)-1] = '_';

    hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 /*WINHTTP_FLAG_ASYNC*/);
    if(!hSession)
    {
        // WinHTTP is not available, why?
        return FALSE;
    }

    /* more sane timeouts, shouldn't take longer than 10 seconds for the whole operation to timeout */
    WinHttpSetTimeouts(hSession, 5000, 5000, 5000, 5000);

    hRequest = RequestSubmit(hSession, UPDATE_SERVER, UPDATE_VERSION_FILE);

    if(!hRequest)
    {
        // GET request for version file failed
        return FALSE;
    }

    dwStatus = RequestHeaderDWORD(hRequest, WINHTTP_QUERY_STATUS_CODE);
    dwLength = RequestHeaderDWORD(hRequest, WINHTTP_QUERY_CONTENT_LENGTH);
    type = RequestHeaderString(hRequest, WINHTTP_QUERY_CONTENT_TYPE);

    if(strnicmp(type, "text/plain", 10) == 0)
    {
        if(dwStatus == HTTP_STATUS_OK)
        {
            char *buf = malloc(dwLength+1);
            memset(buf, 0, dwLength+1);
            dwDownloaded = RequestDownloadToMemory(hRequest, buf, dwLength);

            if(buf[dwLength-1] == '\n')
            {
                buf[dwLength-1] = 0;
            }

            int build = atoi(buf);

            char tmp[256];
            sprintf(tmp, "string ver: %s, int ver: %d, our int ver: %d", buf, build, BUILD);
            free(buf);
            MessageBox(NULL, tmp, "CnCNet", MB_OK);
            return FALSE;

            if(build <= BUILD)
            {
                return FALSE;
            }
        }
        else
        {
            // HTTP status was not 200 for version file
            return FALSE;
        }
    }

    WinHttpCloseHandle(hRequest);

    // download update
    hRequest = RequestSubmit(hSession, UPDATE_SERVER, UPDATE_FILE);

    if(!hRequest)
    {
        // GET request for real file failed
        return FALSE;
    }

    dwStatus = RequestHeaderDWORD(hRequest, WINHTTP_QUERY_STATUS_CODE);
    dwLength = RequestHeaderDWORD(hRequest, WINHTTP_QUERY_CONTENT_LENGTH);
    type = RequestHeaderString(hRequest, WINHTTP_QUERY_CONTENT_TYPE);

    HANDLE hFile;

    if(strnicmp(type, "application/", 12) == 0)
    {
        if(dwStatus == HTTP_STATUS_OK)
        {
            GetTempPath(MAX_PATH, lpPathName);
            GetTempFileName(lpPathName, NULL, 0, lpTempFileName);
            hFile = CreateFile(lpTempFileName, GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if(hFile != INVALID_HANDLE_VALUE)
            {
                dwDownloaded = RequestDownloadToFile(hRequest, hFile);
                CloseHandle(hFile);

                if(dwDownloaded == dwLength)
                {
                    // download ok, do rename tricks
                    if(!MoveFile(lpModuleFileName, lpMoveModuleFileName))
                        return FALSE;
                    if(!MoveFile(lpTempFileName, lpModuleFileName))
                        return FALSE;

                    DeleteFile(lpMoveModuleFileName);
                }
            }
        }
        else
        {
            // HTTP status code was not 200
            return FALSE;
        }
    }

    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hSession);

    return TRUE;
}

HINTERNET RequestSubmit(HINTERNET hSession, LPCWSTR host, LPCWSTR file)
{
    HINTERNET hConnect;
    HINTERNET hRequest;
    BOOL bResults;


    hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_PORT, 0);
    if(!hConnect)
    {
        return NULL;
    }

    hRequest = WinHttpOpenRequest(hConnect, NULL, file, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
    if(!hRequest)
    {
        WinHttpCloseHandle(hConnect);
        return NULL;
    }

    bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
    if(!bResults)
    {
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        return NULL;
    }

    bResults = WinHttpReceiveResponse(hRequest, NULL);
    if(!bResults)
    {
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        return NULL;
    }

    return hRequest;
}

DWORD RequestHeaderDWORD(HINTERNET hRequest, DWORD dwFlag)
{
    DWORD64 dwResult = 0;
    DWORD dwSize = sizeof(DWORD);

    if(WinHttpQueryHeaders(hRequest, dwFlag|WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwResult, &dwSize, WINHTTP_NO_HEADER_INDEX))
    {
        return dwResult;
    }

    return FALSE;
}

char *RequestHeaderString(HINTERNET hRequest, DWORD dwFlag)
{
    wchar_t bufW[128];
    static char bufA[128];
    DWORD dwSize = sizeof(bufW);

    if(WinHttpQueryHeaders(hRequest, dwFlag, NULL, bufW, &dwSize, WINHTTP_NO_HEADER_INDEX))
    {
        if(WideCharToMultiByte(CP_ACP, WC_DISCARDNS, bufW, wcslen(bufW), bufA, sizeof(bufA), NULL, NULL) != 0)
        {
            return bufA;
        }
    }

    return NULL;
}

DWORD RequestDownloadToMemory(HINTERNET hRequest, char *buf, DWORD dwBufSize)
{
    DWORD dwSize;
    DWORD dwDownloaded;
    DWORD dwTotal;

    dwTotal = 0;
    do
    {
        dwSize = 0;

        if(!WinHttpQueryDataAvailable( hRequest, &dwSize))
        {
            return dwTotal;
        }

        if(dwSize == 0)
            break;

        if(dwTotal + dwSize > dwBufSize)
        {
            return -1;
        }

        WinHttpReadData(hRequest, buf+dwTotal, dwSize, &dwDownloaded);

        dwTotal += dwDownloaded;

    } while(dwSize > 0);

    return dwTotal;
}

DWORD RequestDownloadToFile(HINTERNET hRequest, HANDLE hFile)
{
    DWORD dwSize;
    DWORD dwDownloaded;
    DWORD dwTotal;
    DWORD dwBufSize;
    DWORD dwWritten;
    char *buf;

    dwTotal = 0;
    dwBufSize = 0;
    buf = NULL;
    do
    {
        dwSize = 0;

        if(!WinHttpQueryDataAvailable( hRequest, &dwSize) || dwSize == 0)
        {
            break;
        }

        if(dwSize > dwBufSize)
        {
            if(buf)
            {
                buf = realloc(buf, dwSize);
            }
            else
            {
                buf = malloc(dwSize);
            }

            if(!buf)
            {
                return -1;
            }

            dwBufSize = dwSize;
        }

        WinHttpReadData(hRequest, buf, dwSize, &dwDownloaded);

        if(WriteFile(hFile, buf, dwDownloaded, &dwWritten, NULL) == FALSE)
        {
            printf("WriteFile failed\n");
        }

        dwTotal += dwDownloaded;

    } while(dwSize > 0);

    if(buf)
    {
        free(buf);
    }

    return dwTotal;
}

#endif
